#include <memory>
#include "OssManage.h"

using namespace std;

OssManage::OssManage()
{
    // 初始化网络环境
    InitializeSdk();
}

OssManage::~OssManage()
{
    // 释放网络环境
    ShutdownSdk();
}

void OssManage::InitOssClient(string &EndPoint, string &Region, string &BucketName, string &OriginPath)
{
    m_oconf.EndPoint = EndPoint;
    m_oconf.Region = Region;
    m_oconf.BucketName = BucketName;
    m_oconf.OriginPath = OriginPath;

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;

    if(!m_client){
        auto credentialsProvider = make_shared<EnvironmentVariableCredentialsProvider>();
        m_client = make_shared<OssClient>(EndPoint, credentialsProvider, conf);
    }
    m_client->SetRegion(m_oconf.Region);
}

int OssManage::OssSimpleUpload(string &userName, string &fileName, string &&content)
{
    string ObjectName = m_oconf.OriginPath + userName + "/" + fileName;
    shared_ptr<iostream> ios = make_shared<stringstream>(std::move(content));

    PutObjectRequest request(m_oconf.BucketName, ObjectName, ios);
    auto outcome = m_client->PutObject(request);

    if (!outcome.isSuccess()) {
#ifdef DEBUG
        cout << "[ERROR] " << "PutObject fail" << endl;
        cout << "[ERROR] " << "code:" << outcome.error().Code() << endl;
        cout << "[ERROR] " << "message:" << outcome.error().Message() << endl;
        cout << "[ERROR] " << "requestId:" << outcome.error().RequestId() << endl;
#endif
        return -1;
    }
    return 0;
}

int OssManage::OssSimpleUploadLocal(const string &path)
{
    // 处理路径，匹配oss上的路径
    auto it = path.find("/");
    string ossPath = path.substr(++it);
    string ObjectName = m_oconf.OriginPath + ossPath;
#ifdef DEBUG
        cout << "[DEBUG] " << "consumer -----> " << ObjectName << endl;
#endif
    auto outcome = m_client->PutObject(m_oconf.BucketName, ObjectName, path);

    if (!outcome.isSuccess()) {
#ifdef DEBUG
        cout << "[ERROR] " << "PutObject fail" << endl;
        cout << "[ERROR] " << "code:" << outcome.error().Code() << endl;
        cout << "[ERROR] " << "message:" << outcome.error().Message() << endl;
        cout << "[ERROR] " << "requestId:" << outcome.error().RequestId() << endl;
#endif
        return -1;
    }
    return 0;   
}

shared_ptr<OssManage> OssManage::m_oss = nullptr;